    /*
 *   Thing Game Library
 *   Copyright (C)2005 - 2010 Eduardo Nunes Pereira (eduardonunesp at gmail dot com)
 *
 *   This program/library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 *   This program/library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 *    You should have received a copy of the GNU Lesser General Public
 * License along with this program/library ; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <SDL/SDL_image.h>
#include <SDL/SDL_rotozoom.h>

#include "image.hpp"
#include "globals.hpp"
#include "format.hpp"


Image::Image(SDL_Surface *image, bool has_alpha_channel, Uint8 *alpha_channel):
    _alpha(1.0f),
    _has_alpha_channel(has_alpha_channel),
    _sdl_surface(image),
    _alpha_channel(alpha_channel)
{
    _bounds.x = 0;
    _bounds.y = 0;

    _loaded = false;

    if (_sdl_surface)
    {   
        _bounds.w = _sdl_surface->w;
        _bounds.h = _sdl_surface->h;

        _loaded = true;
    }   
    else
        Globals::logger->log(
          "Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
}

Resource *Image::load(void *buffer, unsigned int buffer_size)
{
    /* Load the raw file data from the buffer in an RWops structure */
    SDL_RWops *rw = SDL_RWFromMem(buffer, buffer_size);
    SDL_Surface *tmp_image = IMG_Load_RW(rw, 1); 

    if (!tmp_image)
    {   
        Globals::logger->log(Format("Error, image load failed: %s") % IMG_GetError());
        return NULL;
    }   

    bool has_alpha = false;

    /* The alpha channel to be filled with alpha values */
    Uint8 *alpha_channel = new Uint8[tmp_image->w * tmp_image->h];

    if (tmp_image->format->BitsPerPixel == 32) {
        /* Figure out whether the image uses its alpha layer */
        for (int i = 0; i < tmp_image->w * tmp_image->h; ++i) {
            Uint8 r, g, b, a;
            SDL_GetRGBA(
                    ((Uint32*) tmp_image->pixels)[i],
                    tmp_image->format,
                    &r, &g, &b, &a);

            if (a != 255)
                has_alpha = true;

            alpha_channel[i] = a;
        }
    }

    SDL_Surface *image;

    /* Convert the surface to the current display format */
    if (has_alpha)
        image = SDL_DisplayFormatAlpha(tmp_image);
    else {
        image = SDL_DisplayFormat(tmp_image);

        /* We also delete the alpha channel since it's not used. */
        delete[] alpha_channel;
        alpha_channel = NULL;
    }

    SDL_FreeSurface(tmp_image);

    if (!image) {
        Globals::logger->log("Error: Image convert failed.");
        delete[] alpha_channel;
        return NULL;
    }

    return new Image(image, has_alpha, alpha_channel);
}
